import PackageInfo from '../package.json'
import {FormMode} from "./typing/enums";
import BaseConfig from "./typing/base-config";
import RootContainer from "./using/root-container";
import {DefaultBaseConfig} from "./using/defaults/base-config";
import DefaultRootContainerConfig from "./using/defaults/root-container-config";
import {merge} from 'lodash-es'
import RootContainerDesign from "./design/root-container-design";

export default class DyForm {

    private readonly _root: HTMLElement;
    private readonly _version = PackageInfo.version
    private readonly _mode: FormMode;

    private _rootContainer: RootContainer;

    constructor(container: string | HTMLElement, mode: FormMode = FormMode.USING, private readonly config: BaseConfig) {
        if (!container) {
            throw new Error('container can not be null.')
        }
        if (typeof container === 'string') {
            this._root = document.getElementById(container);
        } else {
            this._root = container
        }
        this._mode = mode
        this.config = merge(DefaultBaseConfig.DEFAULT, this.config)
        this.init()
    }

    private init() {

        this._root.attributeStyleMap.set('display', 'flex')
        this._root.attributeStyleMap.set('overflow', 'auto')
        this._root.attributeStyleMap.set('height', (this.config.height || DefaultBaseConfig.DEFAULT.height) + 'px')

        if (this._mode === FormMode.USING) {
            this._root.attributeStyleMap.set('width', (this.config.width || DefaultBaseConfig.DEFAULT.width) + 'px')
            this._rootContainer = new RootContainer(this.config.rootContainer || DefaultRootContainerConfig.DEFAULT,
                this.config.fieldConfigs, this);
            this._root.appendChild(this._rootContainer.el);
        } else if (this._mode === FormMode.DESIGN) {
            this._root.attributeStyleMap.set('width', 'calc(100vw - 28px)')
            const containerDesign = new RootContainerDesign(this.config.rootContainer || DefaultRootContainerConfig.DEFAULT,
                this.config.fieldConfigs, this);
            this._rootContainer = containerDesign

            this._root.appendChild(containerDesign.getFormConfigEl());
            this._root.appendChild(this._rootContainer.el);
            this._root.appendChild(containerDesign.getElementConfigEl());
        } else {
            throw new Error('unsupported mode ' + this._mode)
        }
    }

    public collectValues() {
        return this._rootContainer.collectValues()
    }

    public getConfig() {
        return this.config
    }

    public generateConfig() {

        const container = this._rootContainer as RootContainerDesign
        return {
            rootContainer: container.getConfig(),
            fieldConfigs: container.getFieldConfigs()
        }
    }
}
